/**
 * PrivilegeFilter.java
 */
package org.yate.oa.controller.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.support.WebApplicationContextUtils;
import org.yate.oa.model.LoginEntity;
import org.yate.oa.model.PrivilegeEntity;
import org.yate.oa.service.IPrivilegeService;
import org.yate.oa.utils.Constants;

/**
 * @author Yate
 * @date Nov 14, 2013
 * @description TODO
 * @version 1.0
 */
//@WebFilter(urlPatterns = { "/*" }, initParams = {
//		@WebInitParam(name = "protect", value = "/.*,/jsp/.*"),
//		@WebInitParam(name = "fModule", value = "/jsp/other/.*,.*\\.html,/user/post"),
//		@WebInitParam(name = "static", value = ".*/css/.*,.*/js/.*,.*/images/.*,/login.jsp,/login/post,/index.jsp,/login.delete") })
public class PrivilegeFilter extends BaseFilter {
	private List<String> filters = new ArrayList<String>();
	private List<String> noFilters = new ArrayList<String>();
	private List<String> fModule = new ArrayList<String>();

//	private final Pattern p = Pattern.compile("/jsp/(w+)/.*");

	private IPrivilegeService ps;

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		if (this.context == null) {
			this.context = filterConfig.getServletContext();
			this.springCtx = WebApplicationContextUtils
					.getWebApplicationContext(this.context);
			this.ps = (IPrivilegeService) this.springCtx
					.getBean("privilegeService");
		}

		String value = filterConfig.getInitParameter("protect");
		if (value != null) {
			StringTokenizer st = new StringTokenizer(value.trim(), ",");
			while (st.hasMoreTokens()) {
				filters.add(st.nextToken());
			}
		}

		value = filterConfig.getInitParameter("fModule");
		if (value != null) {
			StringTokenizer st = new StringTokenizer(value.trim(), ",");
			while (st.hasMoreTokens()) {
				fModule.add(st.nextToken());
			}
		}

		value = filterConfig.getInitParameter("static");
		if (value != null) {
			StringTokenizer st = new StringTokenizer(value.trim(), ",");
			while (st.hasMoreTokens()) {
				noFilters.add(st.nextToken());
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
	 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
	 */
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		final HttpServletRequest req = (HttpServletRequest) request;
		final String path = req.getServletPath();
//		final String method = req.getMethod();

		for (String t : noFilters) {
			if (path.matches(t)) {
				chain.doFilter(request, response);
				return;
			}
		}

		final HttpSession s = req.getSession();
		final LoginEntity ue = (LoginEntity) s
				.getAttribute(Constants.SESSION_USER_ENTITY);
		if (s == null || s.isNew() || ue == null) {
			req.getRequestDispatcher("/login.jsp").forward(request, response);
			return;
		}

		for (String t : fModule) {
			if (path.matches(t)) {
				chain.doFilter(request, response);
				return;
			}
		}
		
		PrivilegeEntity p = ps.getEntitiesByUIDAndURL(ue.getUserId(), path);
		if (p == null) {
			req.getRequestDispatcher("/info.html").forward(request, response);
			return;
		}

		chain.doFilter(request, response);
		return;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.Filter#destroy()
	 */
	@Override
	public void destroy() {
		this.filters.clear();
		this.noFilters.clear();
		this.fModule.clear();
	}

}
